﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Spinning.Spinning.Unitity;
using Box2D.XNA;
using Microsoft.Xna.Framework;
using Spinning.Spinning.Entity.Scenes;
using Spinning.Spinning.UI;

namespace Spinning.Spinning.Entity
{
    class EnemyBoss : SingleGamePlayer
    {
        Random random;
        
        public delegate void OnSpecialAttackHandler();
        public OnSpecialAttackHandler OnBeginSpecialAttackEvent, OnEndSpecialAttackEvent;

        public EnemyBoss()
            : base()
        {
            Physic_Type = PhysicType.Boss;
            ZIndex = Constants.enemy;
            _attackType = AttackType.Default;
            Attack_Mode = AttackMode.Normal;
            random = new Random();
            ColdDownTime = 5;
            EffectTime = 1;
        }

        public enum AttackMode
        {
            Crazy, Normal
        }

        public AttackMode Attack_Mode
        {
            get;
            set;
        }

        public override void OnCreatBody(World world, PhysicConnectManager connectManager)
        {
            base.OnCreatBody(world, connectManager);
            Filter filter=new Filter();
            filter.categoryBits = (ushort)Constants.CategoryBitsBoss;
            filter.maskBits = (ushort)Constants.MaskBitsBoss;
            Filter = filter;
            _fixture.SetRestitution(1);
            _fixture.SetDensity(Constants.playerDensity);
        }

        public int ColdDownTime  //CD時間
        {
            get;
            set;
        }
        public int EffectTime   //作用時間
        {
            get;
            set;
        }

        int tempTimer, CDtimer;
        bool isUsedSkill = true; //開場先無法使用屬性攻擊
        protected override void UpdateSelf(GameTime gameTime)
        {
            base.UpdateSelf(gameTime);
            if (!IsGamePause)
            {
                int delta = gameTime.ElapsedGameTime.Milliseconds;
                if (isUsedSkill)
                {
                    tempTimer += delta;
                    if (tempTimer / 1000 > 1)  //1秒
                    {
                        tempTimer = tempTimer % 1000;
                        CDtimer++;
                        if (CDtimer == EffectTime) //作用時間
                        {
                            _attackType = AttackType.Default;
                            if (OnEndSpecialAttackEvent != null)  //結束攻擊的時間點
                            {
                                OnEndSpecialAttackEvent();
                            }
                        }
                        if (CDtimer == ColdDownTime + EffectTime) //屬性CD
                        {
                            CDtimer = 0;
                            isUsedSkill = false;
                        }
                    }
                }

                int randomNumber = random.Next(5, 10);
                if (LifeTime % randomNumber == 0) Attack_Mode = AttackMode.Crazy;
                if (LifeTime % randomNumber == 1 && isUsedSkill == false)  //開始屬性攻擊時間點
                {
                    isUsedSkill = true;
                    _attackType = Attack_Type;
                    if (OnBeginSpecialAttackEvent != null)
                    {
                        OnBeginSpecialAttackEvent();
                    }
                }
            }
        }

        public override void BeginContact(PhysicSprite other)
        {
            base.BeginContact(other);
            //Actor other = (Actor)_other;
            if (other.Physic_Type == PhysicType.Player)
            {
                SingleGamePlayer player = (SingleGamePlayer)other;
                player.OnTouchedByActor(this);
                isFlash = true;
            }
        }

        int waterShield = 3;

        public override void OnTouchedByActor(PhysicSprite actor)
        {
            if (actor.Physic_Type == PhysicType.Player)
            {
                SingleGamePlayer player = (SingleGamePlayer)actor;
                if (Attack_Type == AttackType.Water && waterShield > 0)  //水屬性開盾
                {
                    MovableTextEntity blockText = new MovableTextEntity();
                    ResourceManager.ContentRoot = "";
                    blockText.fontString = "CenturyGothicBold";
                    blockText.OnLoad();
                    blockText.Origin = new Vector2(0.5f);
                    blockText.Position = new Vector2(0, -10);
                    blockText.Color = Color.Black;
                    blockText.ZIndex = Constants.debugText;
                    blockText.Static = false;
                    Attach(blockText);
                    blockText.Time = 1;
                    blockText.Path = new Vector2(0, -30);
                    blockText.Value = "Block!";
                    waterShield--;
                }
                else
                {
                    switch (player._attackType)
                    {
                        case AttackType.Fire:
                            MinusLifeTime(3);
                            break;
                        case AttackType.Water:
                            MinusLifeTime(2);
                            break;
                        case AttackType.Wind:
                            MinusLifeTime(3);
                            break;
                        case AttackType.Default:
                            MinusLifeTime(1);
                            break;
                    }
                }
            }
        }

        protected SingleGamePlayer Player { get { return ((SinglePlayerScene)Parent).Player; } }

        Vector2 toPlayVelocity;
        public override void HowToMove(GameTime gameTime)
        {
            int terminalVelocity = 20;
            Vector2 bossVelocity = new Vector2();
            Vector2 playerPos = Player.Position;
            float distance = (float)Math.Sqrt((playerPos.X - Position.X) * (playerPos.X - Position.X) + (playerPos.Y - Position.Y) * (playerPos.Y - Position.Y));
            toPlayVelocity = new Vector2(((playerPos.X - (Position.X + _frameSize.X / 2)) / distance) * 3, -((playerPos.Y - (Position.Y + _frameSize.Y / 2)) / distance) * 4f);

            switch (Attack_Mode)
            {
                case AttackMode.Normal:
                    bossVelocity.X = body.GetLinearVelocity().X;
                    bossVelocity.Y = body.GetLinearVelocity().Y;
                    break;
                case AttackMode.Crazy:
                    bossVelocity.X = body.GetLinearVelocity().X + toPlayVelocity.X;
                    bossVelocity.Y = body.GetLinearVelocity().Y + toPlayVelocity.Y;
                    Attack_Mode = AttackMode.Normal;
                    break;
            }

            if (bossVelocity.X > terminalVelocity) bossVelocity.X = terminalVelocity;
            if (bossVelocity.X < -terminalVelocity) bossVelocity.X = -terminalVelocity;

            if (bossVelocity.Y > terminalVelocity) bossVelocity.Y = terminalVelocity;
            if (bossVelocity.Y < -terminalVelocity) bossVelocity.Y = -terminalVelocity;
            body.SetLinearVelocity(bossVelocity);
        }
    }
}
